#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "ESP8266.h"
#include "FreeRTOS.h"
#include "JSON_app.h"
#include "cmsis_os.h"
#include "dma.h"
#include "gpio.h"
#include "main.h"
#include "operation.h"
#include "semphr.h"
#include "servo.h"
#include "stm32f1xx_hal.h"
#include "task.h"

int rx_index = 0;
char rx_buffer[MAX_RX_BUF_SIZE] = {0};
static char send_AT_buffer[MAX_TX_BUF_SIZE] = {0};
static char send_CMD_buffer[MAX_TX_BUF_SIZE] = {0};
static char send_MQTT_buffer[MAX_TX_BUF_SIZE] = {0};

// 全局变量记录ESP8266状态
ESP8266_State esp8266_state = ESP8266_INITIALIZING;

const char *mqttClientId = MQTT_CLIENT_ID;
const char *mqttUsername = MQTT_USERNAME;
const char *mqttPassword = MQTT_PASSWORD;

// 消息队列句柄
SemaphoreHandle_t commandHandlerSemaphore;
osThreadId commandHandlerTaskHandle;

MessageKeyValue kvp;

// 处理服务器控制指令的函数
void HandleServerCommand(const char *command)
{
    if (parse_mqtt_message(&kvp, command))
    {
        handle_message(&kvp);
    }
}

// 命令处理线程函数
void commandHandlerTask(void const *argument)
{
    xSemaphoreTake(commandHandlerSemaphore, portMAX_DELAY);
    while (1)
    {
        HAL_UART_DMAStop(&USART);
        rx_buffer[rx_index] = 0;
        HandleServerCommand(rx_buffer);
        rx_index = 0;
        HAL_UARTEx_ReceiveToIdle_DMA(&USART, (uint8_t *)rx_buffer, MAX_RX_BUF_SIZE);
        xSemaphoreTake(commandHandlerSemaphore, portMAX_DELAY);
    }
}

static void AT_send_cmd(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    vsnprintf(send_AT_buffer, MAX_TX_BUF_SIZE, format, args);
    va_end(args);
    HAL_UART_Transmit(&USART, (uint8_t *)send_AT_buffer, strlen(send_AT_buffer), HAL_MAX_DELAY);
}

bool ESP8266_Cmd(char *cmd, uint32_t waittime, ...)
{
    va_list args;
    char *reply;
    bool result = false;
    rx_index = 0;
    HAL_UARTEx_ReceiveToIdle_DMA(&USART, (uint8_t *)rx_buffer, MAX_RX_BUF_SIZE);
    AT_send_cmd("%s\r\n", cmd);
    osDelay(waittime);
    rx_buffer[rx_index] = '\0';
    HAL_UART_DMAStop(&USART);
    va_start(args, waittime);
    reply = va_arg(args, char *);
    if (reply == NULL)
    {
        va_end(args);
        return true;
    }
    do
    {
        if (strstr((const char *)rx_buffer, reply))
        {
            result = true;
            break;
        }
    } while ((reply = va_arg(args, char *)) != NULL);
    va_end(args);
    return result;
}

// 初始化ESP8266模块的辅助函数
static bool init_esp8266_reset(void)
{
    return ESP8266_Cmd("AT+RST", 2000, "ready", "OK", NULL);
}

static bool init_esp8266_echo(void)
{
    return ESP8266_Cmd("ATE1", 200, "OK", NULL);
}

static bool init_esp8266_wifi_mode(void)
{
    return ESP8266_Cmd("AT+CWMODE=1", 800, "OK", NULL);
}

static bool init_esp8266_connect_wifi(void)
{
    sprintf(send_CMD_buffer, "AT+CWJAP=\"%s\",\"%s\"", WiFi_Name, WiFi_PassWord);
    return ESP8266_Cmd(send_CMD_buffer, 3000, "OK", NULL);
}

static bool init_esp8266_mqtt_user(void)
{
    sprintf(send_CMD_buffer, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"", mqttClientId, mqttUsername, mqttPassword);
    return ESP8266_Cmd(send_CMD_buffer, 1000, "OK", NULL);
}

static bool init_esp8266_mqtt_connect(void)
{
    sprintf(send_CMD_buffer, "AT+MQTTCONN=0,\"%s\",%d,1", MQTT_URL, MQTT_PORT);
    return ESP8266_Cmd(send_CMD_buffer, 1000, "OK", NULL);
}

static bool init_esp8266_mqtt_subscribe(void)
{
    sprintf(send_CMD_buffer, "AT+MQTTSUB=0,\"%s\",1", SUBSCRIBE_TOPIC);
    return ESP8266_Cmd(send_CMD_buffer, 1000, "OK", NULL);
}

bool ESP8266_Init(void)
{
    commandHandlerSemaphore = xSemaphoreCreateBinary();
    if (commandHandlerSemaphore == NULL)
    {
        return false;
    }
    osThreadDef(commandHandlerTask, commandHandlerTask, osPriorityNormal, 0, 512);
    commandHandlerTaskHandle = osThreadCreate(osThread(commandHandlerTask), NULL);
    if (commandHandlerTaskHandle == NULL)
    {
        return false;
    }
    cJSON_APP_Init();

    // 步骤1: 重置模块并等待就绪
    while (!init_esp8266_reset());

    // 步骤2: 启用命令回显
    while (!init_esp8266_echo());

    // 步骤3: 设置WiFi模式为STA
    while (!init_esp8266_wifi_mode());

    // 步骤4: 连接WiFi
    while (!init_esp8266_connect_wifi());

    // 步骤5: 配置MQTT用户
    while (!init_esp8266_mqtt_user());

    // 步骤6: 连接MQTT服务器
    while (!init_esp8266_mqtt_connect());

    // 步骤7: 订阅MQTT主题
    while (!init_esp8266_mqtt_subscribe());

    // 初始化完成，切换到运行状态
    esp8266_state = ESP8266_RUNNING;
    // 启动DMA接收
    rx_index = 0;
    HAL_UARTEx_ReceiveToIdle_DMA(&USART, (uint8_t *)rx_buffer, MAX_RX_BUF_SIZE);
    return true;
}

bool MQTT_Publish(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    int len = vsnprintf(send_MQTT_buffer, MAX_TX_BUF_SIZE - 1, format, args);
    va_end(args);

    if (len < 0 || len >= MAX_TX_BUF_SIZE) return false;

    char cmd_buffer[MAX_TX_BUF_SIZE];
    int ret = sprintf(cmd_buffer, "AT+MQTTPUBRAW=0,\"%s\",%d,0,0", PUBLISH_TOPIC, len);
    if (ret < 0 || ret >= sizeof(cmd_buffer)) return false;

    if (!ESP8266_Cmd(cmd_buffer, 200, "OK", NULL)) return false;
    if (!ESP8266_Cmd(send_MQTT_buffer, 500, "+MQTTPUB:OK", NULL)) return false;

    return true;
}

static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart == &USART)
    {
        rx_index = Size;
        rx_buffer[rx_index] = '\0';

        switch (esp8266_state)
        {
        case ESP8266_INITIALIZING:
            break;
        case ESP8266_RUNNING:
            xSemaphoreGiveFromISR(commandHandlerSemaphore, &xHigherPriorityTaskWoken);
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
            break;
        default:
            break;
        }
    }
    // if (huart == &huart3)
    // {
    //     if (rx_buffer[rx_index - 1] == '\n')
    //     {
    //         rx_complete = 1;
    //     }
    //     else
    //     {
    //         HAL_UART_Receive_IT(&huart3, &rx_buffer[rx_index++], 1);
    //     }
    // }
}
